Only doctest rlibs
authorAlex Crichton <alex@alexcrichton.com>
Thu, 9 Apr 2015 17:43:49 +0000 (10:43 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 10 Apr 2015 17:38:42 +0000 (10:38 -0700)
This commit fixes two problems in Cargo:

1. Only libraries targets that produce an rlib can be doc tested
2. Only the rlib output can be doc tested

The rationale for this is listed in listed in the comments of the commit.

Closes #1496

src/cargo/core/manifest.rs
src/cargo/ops/cargo_test.rs
tests/test_cargo_test.rs

index e9e42cdebae660265e9dd2df510ff5acc53de713..e9b9e154a7f5c0e503830f81b28f6a269acda5ad 100644 (file)
@@ -329,10 +329,18 @@ impl Target {
     pub fn tested(&self) -> bool { self.tested }
     pub fn harness(&self) -> bool { self.harness }
     pub fn documented(&self) -> bool { self.doc }
-    pub fn doctested(&self) -> bool { self.doctest }
     pub fn for_host(&self) -> bool { self.for_host }
     pub fn benched(&self) -> bool { self.benched }
 
+    pub fn doctested(&self) -> bool {
+        self.doctest && match self.kind {
+            TargetKind::Lib(ref kinds) => {
+                kinds.contains(&LibKind::Rlib) || kinds.contains(&LibKind::Lib)
+            }
+            _ => false,
+        }
+    }
+
     pub fn allows_underscores(&self) -> bool {
         self.is_bin() || self.is_example() || self.is_custom_build()
     }
index bc2efd22c20fd92147d53f7739375949f625d23e..ab4c1fde3e06d5627087470d3b6dfc208fb2436d 100644 (file)
@@ -1,4 +1,4 @@
-use std::ffi::OsString;
+use std::ffi::{OsString, OsStr};
 use std::path::Path;
 
 use core::Source;
@@ -55,6 +55,19 @@ pub fn run_tests(manifest_path: &Path,
 
         for (_, libs) in compile.libraries.iter() {
             for &(ref name, ref lib) in libs.iter() {
+                // Note that we can *only* doctest rlib outputs here.  A
+                // staticlib output cannot be linked by the compiler (it just
+                // doesn't do that). A dylib output, however, can be linked by
+                // the compiler, but will always fail. Currently all dylibs are
+                // built as "static dylibs" where the standard library is
+                // statically linked into the dylib. The doc tests fail,
+                // however, for now as they try to link the standard library
+                // dynamically as well, causing problems. As a result we only
+                // pass `--extern` for rlib deps and skip out on all other
+                // artifacts.
+                if lib.extension() != Some(OsStr::new("rlib")) {
+                    continue
+                }
                 let mut arg = OsString::from(name);
                 arg.push("=");
                 arg.push(lib);
index d57c068297826c55a1dfb6e836d0193c501aed13..dfe66cf948c3565ce409d52b94dbcaa2a907403d 100644 (file)
@@ -705,15 +705,8 @@ test foo ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 
-{doctest} foo
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
 ",
                        compiling = COMPILING, running = RUNNING,
-                       doctest = DOCTEST,
                        dir = p.url())));
     p.root().move_into_the_past().unwrap();
     assert_that(p.cargo("test"),
@@ -733,15 +726,8 @@ test foo ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 
-{doctest} foo
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
 ",
-                       running = RUNNING,
-                       doctest = DOCTEST)));
+                       running = RUNNING)));
 
 });
 
@@ -1473,3 +1459,61 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
 ", compiling = COMPILING, running = RUNNING)));
 });
+
+test!(dylib_doctest {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [lib]
+            name = "foo"
+            crate-type = ["rlib", "dylib"]
+            test = false
+        "#)
+        .file("src/lib.rs", r#"
+            /// ```
+            /// foo::foo();
+            /// ```
+            pub fn foo() {}
+        "#);
+
+    assert_that(p.cargo_process("test"),
+                execs().with_stdout(format!("\
+{compiling} foo v0.0.1 ([..])
+{doctest} foo
+
+running 1 test
+test foo_0 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+", compiling = COMPILING, doctest = DOCTEST)));
+});
+
+test!(dylib_doctest2 {
+    // can't doctest dylibs as they're statically linked together
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [lib]
+            name = "foo"
+            crate-type = ["dylib"]
+            test = false
+        "#)
+        .file("src/lib.rs", r#"
+            /// ```
+            /// foo::foo();
+            /// ```
+            pub fn foo() {}
+        "#);
+
+    assert_that(p.cargo_process("test"),
+                execs().with_stdout(""));
+});